package org.dbstar.scheduler.beans;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.dbstar.scheduler.identifier.DefaultIdentifier;
import org.dbstar.scheduler.identifier.Identifier;


/**
 * 复合多个子Job定义的Job定义
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-5-4
 */
public class CompoundJobConf extends JobConf {
	private static final long serialVersionUID = 7449395927859294354L;

	public static final String JOB_TYPE = "compound";

	/**
	 * 组合子Job定义
	 */
	private List<JobDefine> jobList = new ArrayList<JobDefine>();

	@Override
	public final String getType() {
		return JOB_TYPE;
	}

	public final int getJobSize() {
		return jobList.size();
	}

	public final JobDefine getJob(int index) {
		return jobList.get(index);
	}

	public final List<JobDefine> getJobs() {
		return Collections.unmodifiableList(jobList);
	}

	public final void clearJobs() {
		jobList.clear();
	}

	public final void addJob(Identifier jobIdentifier, Map<String, String> parameters, Set<Integer> dependencies,
			String condition) {
		JobDefine define = new JobDefine(jobIdentifier, parameters, dependencies, condition, false);
		if (jobList.contains(define)) {
			throw new IllegalArgumentException("重复的Job: " + jobIdentifier.getStringIdentifier());
		} else {
			jobList.add(define);
		}
	}

	@Override
	public final String getContent() {
		if (jobList.isEmpty()) {
			return null;
		} else {
			JSONArray array = new JSONArray();
			for (JobDefine define : jobList) {
				array.add(buildJsonJob(define));
			}
			return array.toString();
		}
	}

	private static JSONObject buildJsonJob(JobDefine define) {
		JSONObject obj = new JSONObject();
		obj.element("identifier", define.getIdentifier().getStringIdentifier());
		Map<String, String> parameters = define.getParameters();
		if (parameters != null && !parameters.isEmpty()) {
			obj.element("parameters", parameters);
		}
		Set<Integer> dependencies = define.getDependencies();
		if (dependencies != null && !dependencies.isEmpty()) {
			obj.element("dependencies", StringUtils.join(dependencies, ','));
		}
		if (define.getCondition() != null) {
			obj.element("condition", define.getCondition());
		}
		return obj;
	}

	@SuppressWarnings("unchecked")
	@Override
	public final void setContent(String content) {
		clearJobs();
		if (!StringUtils.isBlank(content)) {
			JSONArray array = JSONArray.fromObject(content);
			for (int i = 0, size = array.size(); i < size; i++) {
				JSONObject object = array.getJSONObject(i);
				Identifier identifier = DefaultIdentifier.valueOf(object.getString("identifier"));
				Map<String, String> parameters = (Map<String, String>) object.opt("parameters");
				Set<Integer> dependencies = null;
				String ds = object.optString("dependencies", null);
				if (ds != null) {
					dependencies = new HashSet<Integer>();
					for (String s : StringUtils.split(ds, ',')) {
						dependencies.add(Integer.valueOf(s));
					}
				}
				String condition = object.optString("condition", null);
				addJob(identifier, parameters, dependencies, condition);
			}
		}
	}

	@Override
	public JobConf clone() throws CloneNotSupportedException {
		CompoundJobConf conf = (CompoundJobConf) super.clone();
		conf.jobList = new ArrayList<JobDefine>(jobList.size());
		for (JobDefine jd : jobList) {
			conf.jobList.add(jd.clone());
		}
		return conf;
	}
}
